#include <stdio.h>
#include <string.h>
#include <ctype.h>

#define MAXTOKENLEN 64
#define MAXN 100
//枚举，用于方便判断标识符的类型
enum TYPE{QUALIFIER, CLASS, IDENTIFIER};

typedef struct token{
    char string[MAXTOKENLEN];
    char type;//方便与枚举中的成员进行比较
}Token;
Token stack[MAXN];
Token this;//当前正在处理的标识符
int top = -1;
//top++****
#define push(s) stack[++top] = s
#define pop stack[top--]

enum TYPE get_type()
{
    if(!strcmp(this.string, "const")){ strcpy(this.string, "read-only"); return QUALIFIER; }
    if(!strcmp(this.string, "volatile")) return QUALIFIER;
    if(!strcmp(this.string, "int")) return QUALIFIER;
    if(!strcmp(this.string, "char")) return QUALIFIER;
    if(!strcmp(this.string, "short")) return QUALIFIER;
    if(!strcmp(this.string, "long")) return QUALIFIER;
    if(!strcmp(this.string, "float")) return QUALIFIER;
    if(!strcmp(this.string, "double")) return QUALIFIER;
    else return IDENTIFIER;
}
void get_token()
{
    char *p = this.string;
    //char *p = &this.string;
    while((*p = getchar()) == ' ');
    //******************
    if(isalnum(*p))//只要判断开始的第一个字符就可以判断是否是标识符或者关键字
    {
        while(isalnum(*++p = getchar()));//*++p!!!!!!!!!!
        ungetc(*p, stdin);
        *p = '\0';//添加结束符
        this.type = get_type();
        return;
    }
    if(*p == '*')
    {//指针，特殊处理
        strcpy(this.string, "a pointer pointing to");
        this.type = '*';
        return;
    }
    //其他情况：(,),[,]等等
    this.type = *p;
    *++p = '\0';
    return;
}
void read_first_identifier()
{
    get_token();
    while(this.type != IDENTIFIER)
    {//标识符之前的其他字符先保存到栈中
        push(this);
        get_token();
    }
    printf("%s is ", this.string);
    get_token();
}
void deal_with_function()
{
    char c;
    while((c = getchar()) != ')');//先跳过函数的参数
    printf("a function returning ");
    get_token();
}
void deal_with_arrays()
{
    get_token();
    if(isdigit(this.string[0]))//this.string，参数为字符
    {
        printf("an array 0 - %d of ", atoi(this.string) - 1);
        get_token();//跳过']'
    }else{//']'
        printf("an array ");
    }
    get_token();
}
void deal_with_pointer()
{
    if('*' == stack[top].type)
    {
        printf("%s ", pop.string);
    }
}
void deal_with_declaration()
{
    if('(' == this.type) deal_with_function();
    if('[' == this.type) deal_with_arrays();//~~~~~

    deal_with_pointer();

    while(top >= 0)
    {//递归边界
        if('(' == stack[top].type)
        {
            pop;
            //*************
            get_token();//读取')'之后的符号*****
            deal_with_declaration();
        }else{
            printf("%s ", pop.string);
        }
    }
}
main ()
{
    read_first_identifier();
    deal_with_declaration();
    printf("\n");
    return 0;
}